package org.longteng.monitor.controller;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.longteng.core.base.CommonResult;
import org.longteng.core.utils.Convert;
import org.longteng.monitor.dao.mapper.AppHeartbeatLogMapper;
import org.longteng.monitor.dao.mapper.TimeStatisticsLogMapper;
import org.longteng.monitor.dao.model.AppHeartbeatLog;
import org.longteng.monitor.dao.model.TimeStatisticsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * 接收应用上传监控数据的api
 */
@RestController
@Slf4j
@Validated
@RequestMapping("api")
public class LongtengMonitorController {

    @Autowired
    private TimeStatisticsLogMapper timeStatisticsLogMapper;
    @Autowired
    private AppHeartbeatLogMapper heartbeatLogMapper;

    /**
     * 上传应用工作日志记录序列流
     * @param logObjsFile  工作日志记录序列流
     * @return
     */
    @PostMapping("/worklogobjup")
    public CommonResult<Map<String,Object>> appWorkLogUpload(@RequestParam("logObjs") MultipartFile logObjsFile){
        // 获取文件名
        String fileName = logObjsFile.getOriginalFilename();
        if (log.isDebugEnabled()) {
            log.debug("上传应用工作日志记录序列流. 文件：{}", fileName);
        }
        Map<String,Object> result = new HashMap<>();

        try {
            byte[] data = logObjsFile.getBytes();
            List<Map<String, Object>> maplist = Convert.bytes2MapsUGZIP(data);
            List<TimeStatisticsLog>  list =  Convert.mapsToObjects(maplist, TimeStatisticsLog.class);
            log.debug("反序列化监控日志记录。size:{}", list==null?null:list.size());
            if(CollectionUtil.isEmpty(list)) {
                log.warn("接收到反序列化监控日志记录为空。");
            } else {
                if (log.isDebugEnabled()) {
                    TimeStatisticsLog statisticsLog = list.get(0);
                    log.debug("反序列化监控日志记录。{}\n OutResult:->{}", statisticsLog.getLogId(), statisticsLog.getOutResult());
                }
                int addCount = 0;
                for (TimeStatisticsLog applog: list) {
                    applog.setUpdateDate(new Date());
                    applog.setLogId(null);  // 让它自动编号
                    addCount += timeStatisticsLogMapper.insert(applog);
                }
                result.put("message","接收监控日志记录数据保存成功.记录数:"+addCount);
            }
        } catch (IOException e) {
            log.error("取上传应用工作日志记录序列流错误.", e);
            return CommonResult.failed("选反序列化监控日志记录解析错误.");
        }

        return CommonResult.success(result);
    }

    /**
     * 接收应用心跳状态信息并记录
     * <br>curl http://127.0.0.1:8090/ltmn/api/heartbeatlog?appName=elinkbus&appHost=127.0.0.1&status=OK
     * @param paraMap 参数
     * @return
     */
    @GetMapping("/heartbeatlog")
    public CommonResult<Map<String,Object>> heartbeatLog(@RequestParam Map<String, String> paraMap)  {
        if (log.isDebugEnabled()) {
            log.debug("机器心跳参数。{}", paraMap);
        }
        Map<String,Object> result = new HashMap<>();

        if (paraMap == null) {
            return CommonResult.failed("请传入正确参数：?appName=app[&appHost=192.168&status=OK]。");
        }
        String appName = paraMap.get("appName");
        String appHost = paraMap.get("appHost");
        String status = paraMap.get("status");
        String scope = paraMap.get("scope");

        if(StringUtils.isAnyEmpty(appName, appHost)) {
            return CommonResult.failed("传入参数验证有误！");
        }

        AppHeartbeatLog hartbeatLog = new AppHeartbeatLog();
        hartbeatLog.setLogDate(new Date());
        hartbeatLog.setAppScope(scope==null?"app":scope);
        hartbeatLog.setAppName(appName);
        hartbeatLog.setAppHost(appHost);
        hartbeatLog.setRunStatus(status == null?"":status);
        hartbeatLog.setUpdateDate(new Date());
        try {
            int addCount = heartbeatLogMapper.insert(hartbeatLog);
            result.put("message","接收应用心跳状态数据保存成功.记录数:"+addCount);
        }catch (Exception e) {
            log.error("接收应用心跳状态数据保存失败.",e);
            result.put("message","接收应用心跳状态数据保存失败."+e.getLocalizedMessage());
        }
        return CommonResult.success(result);
    }

    /**
     * 接收应用心跳状态信息并记录
     * <br> curl --data-urlencode 'appName=elinkbus&appHost=127.0.0.1&status=OK' http://127.0.0.1:8090/ltmn/api/heartbeatlog
     * <br>或curl -X POST -H "Content-Type:application/json"  -d '{"appName": "elinkbus", "appHost":"127.0.0.1", "status":"OK"}' http://127.0.0.1:8090/ltmn/api/heartbeatlog
     * @param paraMap 参数
     * @param postMap post json参数
     * @return
     */
    @PostMapping("/heartbeatlog")
    public CommonResult<Map<String,Object>> heartbeatLogPost(@RequestParam Map<String, String> paraMap
            , @RequestBody Map<String, String> postMap)  {
        if (paraMap == null || paraMap.isEmpty() || paraMap.get("appName")==null || paraMap.get("appHost")==null) {
            if (log.isDebugEnabled()) {
                log.debug("接收应用心跳状态信息,为post参数。");
            }
            paraMap = postMap;
        }

        return this.heartbeatLog(paraMap);
    }
}
